﻿using System;
using System.Reflection;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage;

namespace Assist
{
	public class ExtensibleStorageManager
	{
		private static Schema CreateSchema(Autodesk.Revit.DB.Document doc, Guid schemaGuid, object obj)
		{
			Schema schema = Schema.Lookup(schemaGuid);
			bool flag = schema == null;
			if (flag)
			{
				Transaction transaction = new Transaction(doc, "CreateSchema");
				try
				{
					transaction.Start();
					SchemaBuilder schemaBuilder = new SchemaBuilder(schemaGuid);
					Type type = obj.GetType();
					schemaBuilder.SetSchemaName(type.Name);
					foreach (PropertyInfo propertyInfo in type.GetProperties())
					{
						Type propertyType = propertyInfo.PropertyType;
						FieldBuilder fieldBuilder = schemaBuilder.AddSimpleField(propertyInfo.Name, propertyType);
					}
					schema = schemaBuilder.Finish();
					transaction.Commit();
				}
				catch
				{
					transaction.RollBack();
				}
			}
			return schema;
		}

		public static void WriteToElement(Element elem, Guid schemaGuid, object obj)
		{
			Document document = elem.Document;
			Schema schema = Schema.Lookup(schemaGuid);
			Transaction transaction = new Transaction(document, "WriteExtensibleStorage");
			Schema schema2 = ExtensibleStorageManager.CreateSchema(document, schemaGuid, obj);
			bool flag = schema2 != null && schema2.SchemaName == obj.GetType().Name;
			if (flag)
			{
				try
				{
					transaction.Start();
					Entity entity = new Entity(schema2);
					Type type = obj.GetType();
					foreach (PropertyInfo propertyInfo in type.GetProperties())
					{
						Field field = schema2.GetField(propertyInfo.Name);
						object value = propertyInfo.GetValue(obj, null);
						Type propertyType = propertyInfo.PropertyType;
						bool flag2 = propertyType.Name == "String";
						if (flag2)
						{
							entity.Set<string>(field, (string)value);
						}
						else
						{
							bool flag3 = propertyType.Name == "Int32";
							if (flag3)
							{
								entity.Set<int>(field, (int)value);
							}
							else
							{
								bool flag4 = propertyType.Name == "Double";
								if (flag4)
								{
									entity.Set<double>(field, (double)value);
								}
								else
								{
									bool flag5 = propertyType.Name == "Boolean";
									if (flag5)
									{
										entity.Set<bool>(field, (bool)value);
									}
								}
							}
						}
					}
					elem.SetEntity(entity);
					transaction.Commit();
				}
				catch
				{
					transaction.RollBack();
				}
			}
		}

		public static T ReadFromElement<T>(Element elem, Guid schemaGuid)
		{
			Type typeFromHandle = typeof(T);
			T t = (T)((object)Activator.CreateInstance(typeFromHandle));
			Document document = elem.Document;
			Schema schema = Schema.Lookup(schemaGuid);
			bool flag = schema != null && schema.SchemaName == typeof(T).Name;
			if (flag)
			{
				try
				{
					Entity entity = elem.GetEntity(Schema.Lookup(schemaGuid));
					bool flag2 = entity != null;
					if (flag2)
					{
						Type type = t.GetType();
						foreach (PropertyInfo propertyInfo in type.GetProperties())
						{
							Field field = schema.GetField(propertyInfo.Name);
							Type propertyType = propertyInfo.PropertyType;
							bool flag3 = propertyType.Name == "String";
							if (flag3)
							{
								string value = entity.Get<string>(field);
								propertyInfo.SetValue(t, value, null);
							}
							else
							{
								bool flag4 = propertyType.Name == "Int32";
								if (flag4)
								{
									int num = entity.Get<int>(field);
									propertyInfo.SetValue(t, num, null);
								}
								else
								{
									bool flag5 = propertyType.Name == "Double";
									if (flag5)
									{
										double num2 = entity.Get<double>(field);
										propertyInfo.SetValue(t, num2, null);
									}
									else
									{
										bool flag6 = propertyType.Name == "Boolean";
										if (flag6)
										{
											bool flag7 = entity.Get<bool>(field);
											propertyInfo.SetValue(t, flag7, null);
										}
									}
								}
							}
						}
					}
				}
				catch
				{
				}
			}
			return t;
		}
	}
}
